<?php

/**

 * Created by PhpStorm.

 * User: zhangkun

 * Date: 2016/12/5

 * Time: 9:52

 * Description:

 */



//namespace Think\Wechat;




define("TOKEN", "qmjx");

$wechatObj = new wechatCallbackapiTest();

if (!isset($_GET['echostr'])) {

    $wechatObj->responseMsg();

}else{

    $wechatObj->valid();

}
class WechatCallbackapiTest

{

    public function valid()

    {

        $echoStr = $_GET["echostr"];



        //valid signature , option

        if($this->checkSignature()){

            echo $echoStr;

            exit;

        }

    }





    //判断微信接收消息类型,发送人,接收人,以及内容,事件类型

    public function responseMsg()

    {

        //get post data, May be due to the different environments

        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];



        //extract post data

        if (!empty($postStr)){

            /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,

               the best way is to check the validity of xml by yourself */

            libxml_disable_entity_loader(true);

            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);

            $fromUsername = $postObj->FromUserName;

            $toUsername = $postObj->ToUserName;

            $keyword = trim($postObj->Content);

            $time = time();

            $textTpl = "<xml>

							<ToUserName><![CDATA[%s]]></ToUserName>

							<FromUserName><![CDATA[%s]]></FromUserName>

							<CreateTime>%s</CreateTime>

							<MsgType><![CDATA[%s]]></MsgType>

							<Content><![CDATA[%s]]></Content>

							<FuncFlag>0</FuncFlag>

							</xml>";

            if(!empty( $keyword ))

            {

                $msgType = "text";

                $contentStr = "欢迎关注几何夜猫!";

                $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);

                echo $resultStr;

            }else{

                echo "Input something...";

            }



            //绑定信息关联

            $RX_TYPE = trim($postObj->MsgType);



            //判断接收到的信息类型  //示例  接收到文字内容信息调取receiveText读取消息

            //若是关注事件等的操作应当调取receiveEvent事件读取消息



            switch ($RX_TYPE)

            {

                case "text":

                    $resultStr = $this->receiveText($postObj);

                    break;

                case "image":

                    $resultStr = $this->receiveImage($postObj);

                    break;

                case "location":

                    $resultStr = $this->receiveLocation($postObj);

                    break;

                case "voice":

                    $resultStr = $this->receiveVoice($postObj);

                    break;

                case "video":

                    $resultStr = $this->receiveVideo($postObj);

                    break;

                case "link":

                    $resultStr = $this->receiveLink($postObj);

                    break;

                //事件类型

                case "event":

                    $resultStr = $this->receiveEvent($postObj);

                    break;

                default:

                    $resultStr = "unknow msg type: ".$RX_TYPE;

                    break;

            }

            echo $resultStr;

            echo $resultStr;



        }else {

            echo "";

            exit;

        }

    }





    //对于微信来说receiveText即接收用户发送的消息应当调取receiveText函数





    private function receiveText($object)

    {

        $funcFlag = 0;

        $contentStr = "你发送的是文本，内容为：".$object->Content;

        $resultStr = $this->transmitText($object, $contentStr, $funcFlag);

        return $resultStr;

    }



    private function receiveImage($object)

    {

        $funcFlag = 0;

        $contentStr = "你发送的是图片，地址为：".$object->PicUrl;

        $resultStr = $this->transmitText($object, $contentStr, $funcFlag);

        return $resultStr;

    }



    private function receiveLocation($object)

    {

        $funcFlag = 0;

        $contentStr = "你发送的是位置，纬度为：".$object->Location_X."；经度为：".$object->Location_Y."；缩放级别为：".$object->Scale."；位置为：".$object->Label;

        $resultStr = $this->transmitText($object, $contentStr, $funcFlag);

        return $resultStr;

    }



    private function receiveVoice($object)

    {

        $funcFlag = 0;

        $contentStr = "你发送的是语音，媒体ID为：".$object->MediaId;

        $resultStr = $this->transmitText($object, $contentStr, $funcFlag);

        return $resultStr;

    }



    private function receiveVideo($object)

    {

        $funcFlag = 0;

        $contentStr = "你发送的是视频，媒体ID为：".$object->MediaId;

        $resultStr = $this->transmitText($object, $contentStr, $funcFlag);

        return $resultStr;

    }



    private function receiveLink($object)

    {

        $funcFlag = 0;

        $contentStr = "你发送的是链接，标题为：".$object->Title."；内容为：".$object->Description."；链接地址为：".$object->Url;

        $resultStr = $this->transmitText($object, $contentStr, $funcFlag);

        return $resultStr;

    }



    //判断接收事件类型

    private function receiveEvent($object)

    {

        $contentStr = "";

        switch ($object->Event)

        {

            case "subscribe":

//                 $openid= $object->FromUserName;
//                 session('openid',$openid);

                $contentStr[] = array("Title" =>"欢迎关注几何夜猫！",

                    "Description" =>"欢迎关注几何夜猫！",

                    "PicUrl" =>"http://i0.hdslb.com/bfs/live/004bc81276bb89ce761e38a91e59c08481bcd4e4.jpg@320w_200h.webp",

                    "Url" =>"http://www.jihebianli.com/index.php?s=Home/District/town");

            case "unsubscribe":

                break;

            default:

                break;



        }

        if (is_array($contentStr)){

            $resultStr = $this->transmitNews($object, $contentStr);

        }else{

            $resultStr = $this->transmitText($object, $contentStr);

        }

        return $resultStr;

    }

    //回复消息行列

    //文本消息回复

    private function transmitText($object, $content, $flag = 0)

    {

        $textTpl = "<xml>

<ToUserName><![CDATA[%s]]></ToUserName>

<FromUserName><![CDATA[%s]]></FromUserName>

<CreateTime>%s</CreateTime>

<MsgType><![CDATA[text]]></MsgType>

<Content><![CDATA[%s]]></Content>

<FuncFlag>%d</FuncFlag>

</xml>";

        $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content, $flag);

        return $resultStr;

    }



    //主页消息推送图文消息回复

    private function transmitNews($object, $arr_item, $funcFlag = 0)

    {

        //首条标题28字，其他标题39字

        if(!is_array($arr_item))

            return;



        $itemTpl = "    <item>

        <Title><![CDATA[%s]]></Title>

        <Description><![CDATA[%s]]></Description>

        <PicUrl><![CDATA[%s]]></PicUrl>

        <Url><![CDATA[%s]]></Url>

    </item>

";

        $item_str = "";

        foreach ($arr_item as $item)

            $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);



        $newsTpl = "<xml>

<ToUserName><![CDATA[%s]]></ToUserName>

<FromUserName><![CDATA[%s]]></FromUserName>

<CreateTime>%s</CreateTime>

<MsgType><![CDATA[news]]></MsgType>

<Content><![CDATA[]]></Content>

<ArticleCount>%s</ArticleCount>

<Articles>

$item_str</Articles>

<FuncFlag>%s</FuncFlag>

</xml>";



        $resultStr = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item), $funcFlag);

        return $resultStr;

    }





    //验证加密算法

    private function checkSignature()

    {

        // you must define TOKEN by yourself

        if (!defined("TOKEN")) {

            throw new Exception('TOKEN is not defined!');

        }



        $signature = $_GET["signature"];

        $timestamp = $_GET["timestamp"];

        $nonce = $_GET["nonce"];



        $token = TOKEN;

        $tmpArr = array($token, $timestamp, $nonce);

        // use SORT_STRING rule

        sort($tmpArr, SORT_STRING);

        $tmpStr = implode( $tmpArr );

        $tmpStr = sha1( $tmpStr );



        if( $tmpStr == $signature ){

            return true;

        }else{

            return false;

        }

    }

}